import { Pool, PoolOptions, ResultSetHeader, RowDataPacket, createPool } from 'mysql2/promise';

// 默认配置
const defaultOptions: PoolOptions = {
    host: "8.137.110.6",
    port: 8991,
    user: "root",
    password: "058991",
    database: "myonlybase",
};

export default class MySQLPool {
    // 连接池
    private conn: Pool;
    // 连接池选项
    private credentials: PoolOptions;

    constructor(credentials = defaultOptions) {
        this.credentials = credentials;
        this.conn = createPool(this.credentials);
    }

    /** 调用方法前判断断开连接需再次执行链接 */
    private ensureConnection() {
        if (!this?.conn) this.conn = createPool(this.credentials);
    }

    /** 对于`SELECT` and `SHOW`语句，返回对象数据 */
    get queryRows() {
        this.ensureConnection();
        return this.conn.query.bind(this.conn)<RowDataPacket[]>;
    }

    /** 对于`SELECT` and `SHOW`语句，返回数组数据 */
    get queryRowsAsArray() {
        this.ensureConnection();
        return this.conn.query.bind(this.conn)<RowDataPacket[]>;
    }

    /** 对于`INSERT`, `UPDATE`等更改数据的语句（操作单条） */
    get queryResult() {
        this.ensureConnection();
        return this.conn.query.bind(this.conn)<ResultSetHeader>;
    }

    /** 对于`INSERT`, `UPDATE`等更改数据的语句（操作多条）（multipleStatements需设置为true） */
    get queryResults() {
        this.ensureConnection();
        return this.conn.execute.bind(this.conn)<ResultSetHeader>;
    }

    /** 对于`SELECT` and `SHOW`语句，返回对象数据 */
    get executeRows() {
        this.ensureConnection();
        return this.conn.execute.bind(this.conn)<RowDataPacket[]>;
    }

    /** 对于`SELECT` and `SHOW`语句，返回数组数据 */
    get executeRowsAsArray() {
        this.ensureConnection();
        return this.conn.execute.bind(this.conn)<RowDataPacket[]>;
    }

    /** 对于`INSERT`, `UPDATE`等更改数据的语句（操作单条） */
    get executeResult() {
        this.ensureConnection();
        return this.conn.execute.bind(this.conn)<ResultSetHeader>;
    }

    /** 对于`INSERT`, `UPDATE`等更改数据的语句（操作多条）（multipleStatements需设置为true） */
    get executeResults() {
        this.ensureConnection();
        return this.conn.execute.bind(this.conn)<ResultSetHeader>;
    }
}
